<!DOCTYPE html>
<html>
<head>
    <title>Optical System Diagram</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #ccc;
            background-color: #fff;
        }
    </style>
</head>
<body>
    <canvas id="opticalCanvas" width="600" height="450"></canvas>
    <script>
        const canvas = document.getElementById('opticalCanvas');
        const ctx = canvas.getContext('2d');

        // --- Drawing Configuration ---
        const scale = 25; // pixels per cm
        const origin_x = 150;
        const origin_y = 225;
        
        ctx.strokeStyle = '#000';
        ctx.fillStyle = '#000';
        ctx.lineWidth = 2;
        ctx.font = 'bold 16px sans-serif';

        // --- Coordinate Transformation Helpers ---
        function to_cx(x_cm) {
            return origin_x + x_cm * scale;
        }

        function to_cy(y_cm) {
            return origin_y - y_cm * scale;
        }

        // --- Drawing Helper Functions ---
        function drawArrow(fromX, fromY, toX, toY) {
            const headlen = 10; // length of head in pixels
            const dx = toX - fromX;
            const dy = toY - fromY;
            const angle = Math.atan2(dy, dx);
            ctx.beginPath();
            ctx.moveTo(fromX, fromY);
            ctx.lineTo(toX, toY);
            ctx.lineTo(toX - headlen * Math.cos(angle - Math.PI / 6), toY - headlen * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(toX, toY);
            ctx.lineTo(toX - headlen * Math.cos(angle + Math.PI / 6), toY - headlen * Math.sin(angle + Math.PI / 6));
            ctx.stroke();
        }

        function drawDimensionLine(x1, y1, x2, y2, label) {
            ctx.save();
            ctx.lineWidth = 1;
            
            const tickSize = 5;
            if (y1 === y2) { // Horizontal line
                ctx.beginPath();
                ctx.moveTo(x1, y1 - tickSize);
                ctx.lineTo(x1, y1 + tickSize);
                ctx.moveTo(x2, y2 - tickSize);
                ctx.lineTo(x2, y2 + tickSize);
                ctx.moveTo(x1, y1);
                ctx.lineTo(x2, y2);
                ctx.stroke();
                ctx.textAlign = 'center';
                ctx.textBaseline = 'bottom';
                ctx.fillText(label, (x1 + x2) / 2, y1 - 5);
            } else { // Vertical line
                 ctx.beginPath();
                ctx.moveTo(x1 - tickSize, y1);
                ctx.lineTo(x1 + tickSize, y1);
                ctx.moveTo(x2 - tickSize, y2);
                ctx.lineTo(x2 + tickSize, y2);
                ctx.moveTo(x1, y1);
                ctx.lineTo(x2, y2);
                ctx.stroke();
                ctx.textAlign = 'left';
                ctx.textBaseline = 'middle';
                ctx.fillText(label, x1 + 8, (y1 + y2) / 2);
            }
            ctx.restore();
        }
        
        function drawAngleArc(cx, cy, radius, startAngle, endAngle, label, labelPos) {
            ctx.save();
            ctx.lineWidth = 1;
            ctx.beginPath();
            ctx.arc(cx, cy, radius, startAngle, endAngle);
            ctx.stroke();
            ctx.font = '14px sans-serif';
            ctx.fillText(label, labelPos.x, labelPos.y);
            ctx.restore();
        }

        // --- Main Drawing Logic ---
        
        // 1. Principal Axis
        ctx.beginPath();
        ctx.moveTo(0, origin_y);
        ctx.lineTo(canvas.width, origin_y);
        ctx.stroke();

        // 2. Prism System
        const prismHeight = 6;
        const prismWidth = 6;
        
        ctx.beginPath();
        ctx.moveTo(to_cx(-prismWidth), to_cy(0));
        ctx.lineTo(to_cx(0), to_cy(prismHeight));
        ctx.lineTo(to_cx(0), to_cy(-prismHeight));
        ctx.closePath();
        ctx.stroke();
        // Vertical line of the prism
        ctx.beginPath();
        ctx.moveTo(to_cx(0), to_cy(prismHeight));
        ctx.lineTo(to_cx(0), to_cy(-prismHeight));
        ctx.stroke();
        
        // Prism Labels
        ctx.font = '16px sans-serif';
        ctx.fillText('n = 1.5', to_cx(-3.5), to_cy(3));
        drawAngleArc(to_cx(0), to_cy(prismHeight), 20, Math.PI, 1.25*Math.PI, '45°', {x: to_cx(-1.5), y: to_cy(5.2)});
        drawAngleArc(to_cx(0), to_cy(-prismHeight), 20, 0.75*Math.PI, Math.PI, '45°', {x: to_cx(-1.5), y: to_cy(-5.2)});

        // 3. Object representation
        // The triple arrow
        const arrowY = 8;
        const arrowXStart = -4;
        const arrowXEnd = 0;
        ctx.save();
        ctx.lineWidth = 2.5;
        drawArrow(to_cx(arrowXStart), to_cy(arrowY), to_cx(arrowXEnd), to_cy(arrowY));
        ctx.beginPath();
        ctx.moveTo(to_cx(arrowXStart), to_cy(arrowY)-4);
        ctx.lineTo(to_cx(arrowXEnd)-10, to_cy(arrowY)-4);
        ctx.stroke();
        ctx.beginPath();
        ctx.moveTo(to_cx(arrowXStart), to_cy(arrowY)+4);
        ctx.lineTo(to_cx(arrowXEnd)-10, to_cy(arrowY)+4);
        ctx.stroke();
        ctx.restore();
        
        // The vertical arrow and dimension
        drawArrow(to_cx(-1), to_cy(0), to_cx(-1), to_cy(6));
        drawDimensionLine(to_cx(-1.5), to_cy(0), to_cx(-1.5), to_cy(6), '6 cm');
        drawDimensionLine(to_cx(0.5), to_cy(0), to_cx(0.5), to_cy(-6), '6 cm');

        // 4. Lenses
        const lensHeight = 8;
        const lens1_x = 10;
        const lens2_x = 15;
        
        // Convex Lens L1
        ctx.beginPath();
        ctx.moveTo(to_cx(lens1_x), to_cy(lensHeight));
        ctx.quadraticCurveTo(to_cx(lens1_x + 2), to_cy(0), to_cx(lens1_x), to_cy(-lensHeight));
        ctx.quadraticCurveTo(to_cx(lens1_x - 2), to_cy(0), to_cx(lens1_x), to_cy(lensHeight));
        ctx.stroke();
        ctx.textAlign = 'center';
        ctx.fillText('f₁ = 20 cm', to_cx(lens1_x), to_cy(-lensHeight - 1));

        // Concave Lens L2
        ctx.beginPath();
        ctx.moveTo(to_cx(lens2_x), to_cy(lensHeight));
        ctx.quadraticCurveTo(to_cx(lens2_x - 1.5), to_cy(0), to_cx(lens2_x), to_cy(-lensHeight));
        ctx.moveTo(to_cx(lens2_x), to_cy(lensHeight));
        ctx.quadraticCurveTo(to_cx(lens2_x + 1.5), to_cy(0), to_cx(lens2_x), to_cy(-lensHeight));
        ctx.stroke();
        ctx.fillText('f₂ = -10 cm', to_cx(lens2_x), to_cy(-lensHeight - 1));

        // 5. Dimension lines for distances
        drawDimensionLine(to_cx(0), to_cy(8), to_cx(10), to_cy(8), '10 cm');
        drawDimensionLine(to_cx(10), to_cy(8), to_cx(15), to_cy(8), '5 cm');
        
        // 6. Figure Label
        ctx.textAlign = 'center';
        ctx.textBaseline = 'bottom';
        ctx.fillText('Fig. 1.42', canvas.width / 2, canvas.height - 10);

    </script>
</body>
</html>